package pokerclient.core.network;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import common.Message;

/**
 * A thread which continuously listens for information from the server, and
 * sends the information to be processed.
 * 
 * @author Aron Manucheri
 * 
 */
public class ClientListener extends Thread {

	/**
	 * Class variables
	 */
	private Socket listeningSocket = null;
	private Message incomingMsgObject;
	private ObjectInputStream in;
	private Pinger pinger;

	/**
	 * Constructor
	 * 
	 * @param host
	 *            host to connect and listen to
	 * @param port
	 *            port of the host
	 */
	public ClientListener(String host, int port) {
		super("ClientListener");
		try {
			this.listeningSocket = new Socket(host, port); // Create a socket
															// which connects to
															// the server at a
															// specific port.
		} catch (UnknownHostException e) {
			System.out.println("Host unknown");
			e.printStackTrace();
		} catch (ConnectException e) {
			System.out.println("Error. Could not connect to server " + host
					+ " at port: " + port);
		} catch (IOException e) {
			System.out.println("IOException");
			e.printStackTrace();
		} catch (Exception ex) {
			System.out.println("Something horrible has happened.!");
		}
	}

	@Override
	public void run() {
		try {
			pinger = new Pinger(); // create a pinger to get updates
			pinger.start(); // start it.
			startListening();
		} catch (IOException e) {
			try {
				// This is where we end up if the server goes offline
				System.out.println("The server went offline!");
				this.join();
			} catch (InterruptedException e1) {
				// We really shouldn't end up in here
				e1.printStackTrace();
			}
		}
	}

	/**
	 * Starts listening to the socket specified to the ClientListener.
	 * 
	 * @throws IOException
	 */
	public void startListening() throws IOException {
		// Create input stream, that reads from listeningSocket (which is
		// connected to the server)
		in = new ObjectInputStream(listeningSocket.getInputStream());

		try {
			// "Endless"-loop. Keeps listening for incoming messages from the
			// server.
			while ((incomingMsgObject = (Message) in.readObject()) != null) {
				//Process the message, after that reset it, then keep looping.
				ClientProtocol.processMessage(incomingMsgObject);
				incomingMsgObject = null;
			}
		} catch (ClassNotFoundException e) {
			System.out.println("Something went wrong. (ClassNotFound)");
			e.printStackTrace();
		}

		// We are good boys, so we clean up after ourselves when we are done. 
		try {
			pinger.join(); //kill the pingerthread
		} catch (InterruptedException e) {
			// You shouldn't end up here.
			e.printStackTrace();
		}
		in.close(); //close the inputstream.
		listeningSocket.close(); //finally close the socket.
	}

	/**
	 * 
	 * @return the listening socket
	 */
	public Socket getSocket() {
		return listeningSocket;
	}

}
